package com.qikux.listener;

import com.qikux.entity.User;

import javax.servlet.http.HttpSession;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 管理在线人员的类
 */
public class UserManager {

    private Map<User, Set<HttpSession>> online = new ConcurrentHashMap<>();

    /**
     * 判断用户是否在线
     *
     * @param user
     * @param session
     * @return
     */
    public boolean isOnline(User user, HttpSession session) {

        // 根据用户的ID ， 从 map 中查找 对应的人员信息
        User us = online.keySet().stream().filter(u -> Objects.equals(u.getId(), user.getId())).findFirst().orElse(null);

        if (us == null) {
            return false;
        }
        // 如果找到了 user , 说明 在线， 比较 session是否是同一个， 如果是同一个session， 说明是当前用户多次登录
        Set<HttpSession> httpSessions = online.get(us);

        // 判断 session 列表中是否有当前 session
        if (httpSessions.contains(session)) {

            // 如果是 自己， 则认为 不在线，允许再次登录
            return false;
        }
        return true;
    }

    public void addUser(User user, HttpSession session) {
        // 根据用户ID 查询 user
        User us = online.keySet().stream().filter(u -> Objects.equals(u.getId(), user.getId())).findFirst().orElse(null);
        // 如果 us 存在，则 获取 对应的 List , 如果 不存在 new List
        if (us == null) {
            Set<HttpSession> httpSessions = new HashSet<>();
            httpSessions.add(session);
            online.put(user, httpSessions);
            return;
        }
        // 如果存在，则直接获取 List
        Set<HttpSession> httpSessions = online.get(us);
        httpSessions.add(session);
    }

    public void removeUser(User user) {
        online.remove(user);
    }

    public void offLine(User user) {
        // 找到用户管理中存储的用户信息
        User us = online.keySet().stream().filter(u -> Objects.equals(u.getId(), user.getId())).findFirst().orElse(null);

        // 下线
        Set<HttpSession> sessions = online.remove(us);

        // 将里面存储的session全部失效
        sessions.forEach(HttpSession::invalidate);

    }
}
